<?php

namespace Core\Common\Route;

use Core\Common\Base\Config;
use Core\Common\Base\Log;

/**
 * Description of Response
 *
 * @author baiyang
 */
class Response
{
    private static $data = '';
    private static $debug = '';
    //错误码， 前三位为HTTP状态码， 后两位为项目错误码，如: 40101
    private static $code = 1;
    private static $errorClass = '';
    private static $html = false;
    private static $cookie = [];
    private static $header = [];
    private static $contentType = 'text/html; charset=utf-8';
    private static $httpCode = 200;

    public static function reset()
    {
        self::$data = '';
        self::$debug = '';
        self::setCode(1);
        self::$httpCode = 200;
        self::$html = false;
        self::$errorClass = '';
        self::$contentType = 'text/html; charset=utf-8';
        self::$cookie = [];
        self::$header = [];
    }

    public static function succ($data = null, $isHtml = false)
    {
        self::$data = $data;
        self::setCode(1);
        self::$html = $isHtml;
    }

    public static function error($message, $code = 500, $file = null)
    {
        self::$data = $message;
        self::setCode($code);
        self::$errorClass = $file;
        $field = [
            'message' => $message,
            'class' => $file,
        ];
        $tags = [
            'service' => CORE_NAME,
            'uri' => Request::uri(),
            'code' => $code,
        ];
        Log::influxMeasureLog('business', $tags, $field);
    }
    /**
     * 记录一个错误
     * @param array $codeArr [errorCode, errorMessage]
     * @param array $param 如果errorMessage存在%d, %s等格式化变量占位符, param放置具体数值
     */
    public static function trigger(array $codeArr, ...$param)
    {
        list($code, $message) = $codeArr;
        if ($param) {
            $message = sprintf($message, ...$param);
        }
        self::setCode($code);
        self::$data = $message;
        $field = [
            'count' => 1,
        ];
        $tags = [
            'service' => CORE_NAME,
            'uri' => Request::uri(),
            'code' => $code,
        ];
        Log::influxMeasureLog('business', $tags, $field);
    }

    public static function debug($mixed)
    {
        self::$debug .= $mixed;
    }
    
    public static function httpCode($code = null)
    {
        if (is_null($code)) {
            if (Config::config('http_code') && self::$httpCode > 99 && self::$httpCode < 1000) {
                return self::$httpCode;
            }
            return 200;
        }
        if ($code > 99 && $code < 1000) {
            self::$httpCode = $code;
        }
        return null;
    }

    public static function setCookie(
        $name,
        $value = '',
        $expire = 0,
        $path = '/',
        $domain = '',
        $secure = false,
        $httpOnly = false
    ) {
        self::$cookie[] = func_get_args();
    }

    public static function cookie()
    {
        return self::$cookie;
    }
    
    public static function setHeader($key, $value)
    {
        self::$header[$key] = $value;
    }
    
    public static function header()
    {
        return self::$header;
    }

    public static function setCode($code)
    {
        self::$code = $code;
        if ($code > 99 && $code < 1000) {
            self::$httpCode = $code;
        }
    }
    /**
     * 返回响应码
     * @return mixed
     */
    public static function getCode()
    {
        return self::$code;
    }

    public static function contentType()
    {
        if (Request::isGrpc()) {
            return 'application/grpc';
        }
        return self::$contentType;
    }

    public static function setContentType($contentType = 'application/json')
    {
        self::$contentType = $contentType;
    }

    public static function data()
    {
        return self::$data;
    }

    public static function raw()
    {
        return self::$debug . (is_scalar(self::$data) ? self::$data : json_encode(self::$data, JSON_PRETTY_PRINT));
    }

    private static function format($name, $data)
    {
        return '<span style="color: red; ">' . strtoupper($name) . '</span>:<br/>' . (is_scalar($data) ? $data : var_export($data,
                true)) . '<br/>';
    }

    public static function rawResult()
    {
        return array(
            'status_code' => self::$code,
            'data' => self::$data,
        );
    }

    /**
     * 数据返回
     * @return mixed
     */
    public static function result()
    {
        if (Request::isGrpc()) {
            return self::$data;
        }
        if (self::$html) {
            return self::$debug . self::$data;
        }
        if (self::$debug || Request::inDebug()) {
            return '<pre>' . self::format('debug', self::$debug) . self::format('data', self::$data) .
                self::format('errorClass', self::$errorClass) . self::format('server', Request::server())
                . '</pre>';
        }
        self::$contentType = 'application/json';
        if (class_exists('\App\Config\Response') && method_exists('\App\Config\Response', 'result')) {
            return \App\Config\Response::result(self::$code, self::$data);
            //return call_user_func('\App\Config\Response::result', self::$code, self::$data);
        } else {
            $arr = [
                'status_code' => self::$code,
                'data' => (self::$code == 1 ? self::$data : ''),
                'timestamp' => Request::requestTime(),
                'message' => (self::$code > 1 ? self::$data : ''),
            ];
            return json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR);
        }
    }

    /**
     * 遇到FatalError时的返回
     * @param mixed $code
     * @param string $message
     * @param string $file
     * @param int $line
     * @return mixed
     */
    public static function fatalError($code, $message, $file, $line)
    {
        $arr = array(
            'status_code' => $code,
            'data' => '',
            'timestamp' => Request::requestTime(),
            'message' => $message,
        );
        self::$contentType = 'application/json';
        $field = [
            'message' => $message,
            'file' => $file,
            'line' => $line,
        ];
        $tags = [
            'service' => CORE_NAME,
            'uri' => Request::uri(),
            'code' => 500,
        ];
        Log::influxMeasureLog('business', $tags, $field);
        return json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_PRETTY_PRINT);
    }
}
